import sys
import json
import sqlite3
import time
from typing import Any, Union

import PySide6
from PySide6 import QtWidgets, QtCore, QtGui
from PySide6.QtWidgets import QApplication, QMainWindow, QTableView, QWidget, QHeaderView, QMenu, QAbstractItemView, \
    QItemDelegate, QDialog, QStyledItemDelegate, QStyle, QStyleOptionViewItem, QMessageBox, QAbstractItemDelegate
from PySide6.QtCore import Qt, QSortFilterProxyModel, QAbstractItemModel, QMimeData, QObject, QModelIndex, \
    QRegularExpression, Signal, QItemSelectionModel, QItemSelection
from PySide6.QtGui import QCursor, QGuiApplication, QDrag, QRegularExpressionValidator, QColor, QBrush, QPalette

from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlRecord, QSqlIndex

from config.JsonEditDialog import JsonEditDialog


class VarTable(QTableView):
    json_signal = Signal(str)

    def __init__(self, parent=None, configFile=None, columns=None, Ro_flag=False) -> None:
        super().__init__(parent)
        self.Ro_flag = Ro_flag
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(configFile)
        self.db.open()

        # 创建变量
        self.current_index = None           # 创建临时存储焦点的index

        self.timer_setFocus = QtCore.QTimer()       # 用于在调整好顺序后的设置焦点的定时器
        self.timer_setFocus.timeout.connect(self.set_custom_focus)

        self.timer_insert = QtCore.QTimer()         # 用于修改类型号后移动的定时器
        self.timer_insert.timeout.connect(self.insert_suited_row)
        self.insert_src = 0
        self.insert_tar = 0

        # 表格的基本设置
        self.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeMode.ResizeToContents)
        self.horizontalHeader().setDefaultAlignment(
            Qt.AlignmentFlag.AlignCenter)
        self.verticalHeader().setDefaultAlignment(Qt.AlignmentFlag.AlignCenter)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)

        # 创建QSqlTableModel并将其与QTableView关联
        self.tableModel = MySqlTableModel(db=self.db)
        self.tableModel.setTable('var')
        self.tableModel.setPrimaryKey(QSqlIndex('key'))  # 设置主键自增
        self.tableModel.setEditStrategy(
            QSqlTableModel.EditStrategy.OnFieldChange)
        self.setModel(self.tableModel)
        # 设置 json的配置列为单独的列宽，必须放在setmode之后，否则有意外bug
        self.horizontalHeader().setSectionResizeMode(15, QHeaderView.ResizeMode.Fixed)
        self.setColumnWidth(15, 200)

        # 跟踪被修改的列索引
        self.modifiedColumn = -1

        # 设置表格修改的信号
        # self.tableModel.dataChanged.connect(self.data_change_slot)
        self.clicked.connect(self.handleCellClicked)
        self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)
        self.tableModel.select()

        # 设置列标题为中文且只显示部分给用户修改,并限制输入格式
        for i in range(self.tableModel.columnCount()):
            column_name = self.tableModel.record().fieldName(i)
            if column_name in columns.keys():
                self.setItemDelegateForColumn(
                    i, InputDelegate(self, inputType=columns[column_name][2]))
                self.tableModel.setHeaderData(i, Qt.Horizontal,
                                              columns[column_name][1])
            # elif column_name == 'key':
            #     self.tableModel.setHeaderData(i, Qt.Horizontal,
            #                                   'key')

            else:
                self.hideColumn(i)

        # 设置背景颜色
        # customDelegate = CustomDelegate()
        # self.setItemDelegate(customDelegate)
        # self.setItemDelegateForRow(2, MyDelegate())
        # self.setItemDelegate(MyDelegate())
        # self.setStyleSheet("background-color: rgba(255, 0, 0, 100);")

        # 排序
        # self.setSortingEnabled(True)
        self.sortByColumn(0, Qt.SortOrder.AscendingOrder)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        # self.setFocusPolicy(Qt.StrongFocus)

        if self.Ro_flag:
            # 如果已经上线就设置列表为只读
            self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            # 右键菜单
            self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
            self.customContextMenuRequested.connect(self.rightClick_menu)

        # signal
        self.json_signal.connect(self.updateJson)

        self.autoSize()

        # self.update_index()

    """
        双击修改json和更新数据
    """

    def mouseDoubleClickEvent(self, event) -> None:
        """
            弹出jsonEditDialog查看和修改json格式的数据
        """
        index = self.currentIndex()
        var_type = self.tableModel.data(self.tableModel.index(index.row(), 6))
        if index.column() == 15 and var_type in ['bit', 'enum']:
            jsonEditDialog = JsonEditDialog(
                parent=None,
                json_str=self.tableModel.data(index),
                signal=self.json_signal,
                Ro_flag=self.Ro_flag)
            jsonEditDialog.exec()
        return super().mouseDoubleClickEvent(event)

    # def befor_update_slot(self, model, record):
    #     print(model, record)
    #     age = record.value('category_id')
    #     print(age)
    #     record.setValue('type_lv1', age[0])  # 自动生成的第一个字段
    #     record.setValue('type_lv2', age[1])  # 自动生成的第二个字段

    # def data_change_slot(self, index):
    #     """ 表格发生修改触发的信号, 单独用一个函数是为了后期添加其他功能 """
    #     print(index)
    #     row = index.row()
    #     column = index.column()
    #     value = index.data()
    #     if column == 1:
    #         self.tableModel.setData(self.tableModel.index(row, column+1), value + 'ttl')
    #         self.tableModel.select()
    #     pass

    def handleCellClicked(self, index):
        # 记录被点击的单元格的列索引
        self.modifiedColumn = index.column()

    def handleBeforeUpdate(self, rowIndex: int, viewModel: QSqlRecord):
        # 取消信号关联
        self.tableModel.beforeUpdate.disconnect(self.handleBeforeUpdate)
        # self.tableModel.dataChanged.disconnect(self.data_change_slot)
        # 从TableView的click信号中获取修改的列(因为无法从beforeUpdate信号中获取)
        modifiedColumn = self.modifiedColumn
        # 标记记录为已修改
        self.tableModel.setRecord(rowIndex, viewModel)
        # if not self.tableModel.setRecord(rowIndex, viewModel):
        #     error = self.tableModel.lastError()
        #     print("标记记录为已修改时出错:", error.text())
        # 如果是类型号被修改
        # modifiedColumn == list(Config.column_RW.keys()).index('category_id')
        value1 = viewModel.value(1)
        if not value1:
            pass
        elif modifiedColumn == 1:
            # 获取修改的类型号
            value2 = ''
            value3 = ''
            # 从已有的值中获取想要的数据
            for i in range(self.tableModel.rowCount()):
                # 排除自己
                if i == rowIndex:
                    continue
                # 如果 A2 遇到 A2
                if self.tableModel.record(i).value(1) == value1:
                    value2 = self.tableModel.record(i).value(2)
                    value3 = self.tableModel.record(i).value(3)
                    break
                # 如果 A3 遇到 A2
                elif self.tableModel.record(i).value(1)[0] == value1[0]:
                    value2 = self.tableModel.record(i).value(2)
            # 获取要修改的 index
            index2 = self.tableModel.index(rowIndex, 2)
            index3 = self.tableModel.index(rowIndex, 3)
            # 设置值
            if value2:
                self.tableModel.setData(index2, value2, Qt.EditRole)
            if value3:
                self.tableModel.setData(index3, value3, Qt.EditRole)
            self.tableModel.submitAll()
            # 调整位置
            # 从已有的值中获取想要的数据
            value1_lsit = []
            for i in range(self.tableModel.rowCount()):
                value1_lsit.append(self.tableModel.record(i).value(1))
            # print(value1_lsit)
            # print(value1_lsit[rowIndex], value1)
            value1_lsit.pop(rowIndex)
            insert_index = 0
            for i, element in enumerate(value1_lsit):
                if element <= value1:
                    insert_index = i
                else:
                    pass
            # print(insert_index)
            # self.move_row([rowIndex], rowIndex, rowIndex + 1, False)
            if insert_index == rowIndex:
                pass
            elif insert_index > rowIndex:
                # self.move_row([rowIndex], rowIndex, insert_index + 1, False)
                self.insert_src = rowIndex
                self.insert_tar = insert_index + 1
                self.timer_insert.setSingleShot(True)
                self.timer_insert.start(0)
            else:
                # self.move_row([rowIndex], rowIndex, insert_index + 1, False)
                self.insert_src = rowIndex
                self.insert_tar = insert_index + 1
                self.timer_insert.setSingleShot(True)
                self.timer_insert.start(0)
            # self.tableModel.submitAll()
                # selected_rows = [rowIndex]
                # self.delete_rows(selected_rows)
                # destinationRow = insert_index + 1
                # to_move_rowData = [self.tableModel.record(i) for i in selected_rows]
                # selected_rows.sort(reverse=True)  # 从后往前删除行，避免索引改变
                # for row in selected_rows:
                #     self.tableModel.removeRow(row)
                # # self.tableModel.submitAll()
                # self.tableModel.select()

                # update_value = self.get_middle_value_(self.tableModel.record(destinationRow - 1).value(0),
                #                                       self.tableModel.record(destinationRow).value(0),
                #                                       len(selected_rows))
                #
                # for i, rowData in enumerate(to_move_rowData):
                #     rowData.setValue(0, update_value[i])
                #     self.tableModel.insertRecord(destinationRow + i, rowData)
                #
                # self.tableModel.submitAll()
                # # self.rememberState()
                # # self.tableModel.select()
                # # self.restoreState()
                #
                # self.clearSelection()
                # for i, rowData in enumerate(to_move_rowData):
                #     self.setCurrentIndex(self.tableModel.index(destinationRow + i, 0))




        elif modifiedColumn == 2:
            value2 = viewModel.value(2)
            # 从已有的值中获取想要的数据
            for i in range(self.tableModel.rowCount()):
                # 排除自己
                if i == rowIndex:
                    continue
                # 如果类型号 A0 的一级类型被修改 所有的 A 一级类型都要被修改
                if self.tableModel.record(i).value(1)[0] == value1[0]:
                    self.tableModel.setData(self.tableModel.index(i, 2), value2, Qt.EditRole)
        elif modifiedColumn == 3:
            value3 = viewModel.value(3)
            # 从已有的值中设置数据
            for i in range(self.tableModel.rowCount()):
                # 排除自己
                if i == rowIndex:
                    continue
                # 如果类型号 A0 的二级类型被修改 所有的 A0 二级类型都要被修改
                if self.tableModel.record(i).value(1) == value1:
                    self.tableModel.setData(self.tableModel.index(i, 3), value3, Qt.EditRole)
        elif modifiedColumn == 6:
            value6 = viewModel.value(6)
            if (value6 == 'float' or value6 == 'int') and viewModel.value(15):
                self.tableModel.setData(self.tableModel.index(rowIndex, 15), '', Qt.EditRole)

        # # 重新排序位置
        # if self.modifiedColumn == 1 and value1:
        #     self.sortByColumn(1, Qt.SortOrder.AscendingOrder)

        # 重新关联信号
        self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)
        # self.tableModel.dataChanged.connect(self.data_change_slot)
        # self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)
        # 提交事务
        # self.tableModel.submitAll()
        # self.fresh_table()
        # self.current_index = self.tableModel.index(rowIndex, 2)
        # self.timer_setFocus.start(5)

    def data_change_slot(self, topLeft, bottomRight, roles=None):
        pass
        # 取消信号关联
        # # self.tableModel.dataChanged.disconnect(self.data_change_slot)
        # self.tableModel.beforeUpdate.disconnect(self.handleBeforeUpdate)
        # self.tableModel.dataChanged.disconnect(self.data_change_slot)
        # # 获取修改的行
        # row = topLeft.row()
        # value1 = self.tableModel.record(row).value(1)
        # value3 = self.tableModel.record(row).value(3)
        # value4 = self.tableModel.record(row).value(4)
        # value5 = self.tableModel.record(row).value(5)
        # modifiedColumn = self.modifiedColumn
        # if not value1:
        #     pass
        # # elif modifiedColumn == 3:
        # #     # 判断是否重名
        # #     for i in range(self.tableModel.rowCount()):
        # #         # 排除自己
        # #         if i == row:
        # #             continue
        # #         if self.tableModel.record(i).value(1)[0] == value1[0] and self.tableModel.record(i).value(1)[1] != \
        # #                 value1[1] and self.tableModel.record(i).value(3) == value3:
        # #             value3 = 'repeat_err'
        # #             # viewModel.setValue(3, value3)
        # #             self.tableModel.setData(self.tableModel.index(row, 3), value3, Qt.EditRole)
        # #             break
        # # elif modifiedColumn == 4:
        # #     # 判断是否重名
        # #     for i in range(self.tableModel.rowCount()):
        # #         # 排除自己
        # #         if i == row:
        # #             continue
        # #         if self.tableModel.record(i).value(1) == value1 and self.tableModel.record(i).value(4) == value4:
        # #             value4 = 'repeat_err'
        # #             self.tableModel.setData(self.tableModel.index(row, 4), value4, Qt.EditRole)
        # #             break
        # # elif modifiedColumn == 5:
        # #     # 判断是否重名
        # #     for i in range(self.tableModel.rowCount()):
        # #         # 排除自己
        # #         if i == row:
        # #             continue
        # #         if self.tableModel.record(i).value(1) == value1 and self.tableModel.record(i).value(5) == value5:
        # #             value5 = 'repeat_err'
        # #             self.tableModel.setData(self.tableModel.index(row, 5), value5, Qt.EditRole)
        # #             break
        # # self.tableModel.submitAll()
        # # self.fresh_table()
        # # self.current_index = self.tableModel.index(row, 2)
        # # self.timer_setFocus.start(5)
        # # 重新关联信号
        # # self.tableModel.dataChanged.connect(self.data_change_slot)
        # self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)
        # self.tableModel.dataChanged.connect(self.data_change_slot)

    def updateJson(self, json_str):
        """
            jsonEditDialog关闭后更新对应单元格数据
        """
        index = self.currentIndex()
        if json_str == 'null':
            json_str = ''
        self.tableModel.setData(index, json_str)
        self.autoSize()

    """ 右键相关 """

    def rightClick_menu(self):
        """右键菜单"""
        # 获取选择的行
        selected_rows = list(
            set(map(lambda index: index.row(), self.selectedIndexes())))

        # 右键选项设置以及action slot
        self.contextMenu = QMenu()
        self.contextMenu.addAction('添加空行').triggered.connect(self.add_blankRow)
        self.contextMenu.addAction('复制').triggered.connect(
            lambda: self.copy_rows(selected_rows))
        self.contextMenu.addAction('Delete').triggered.connect(
            lambda: self.delete_rows(selected_rows))

        # 弹出右键
        self.contextMenu.popup(QCursor.pos())  # 根据鼠标坐标显示右击菜单
        self.contextMenu.show()

    def add_blankRow(self):
        """在当前位置的下方添加空行"""
        # self.tableModel.dataChanged.disconnect(self.data_change_slot)
        self.tableModel.beforeUpdate.disconnect(self.handleBeforeUpdate)
        selected_row = self.currentIndex().row()
        value = self.get_middle_value(self.tableModel.record(selected_row).value(0), self.tableModel.record(selected_row + 1).value(0), 1)
        self.tableModel.insertRow(selected_row + 1)
        self.tableModel.setData(self.tableModel.index(selected_row + 1, 0), value[0])
        self.tableModel.submitAll()
        # self.tableModel.dataChanged.connect(self.data_change_slot)
        self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)

    def copy_rows(self, selected_rows):
        self.fresh_table()
        to_copy_rowData = [self.tableModel.record(i) for i in selected_rows]
        destinationRow = max(selected_rows)
        update_value = self.get_middle_value(self.tableModel.record(destinationRow).value(0), self.tableModel.record(destinationRow + 1).value(0), len(selected_rows))
        for i, rowData in enumerate(to_copy_rowData):
            rowData.setValue(0, update_value[i])
            self.tableModel.insertRecord(destinationRow + 1 + i, rowData)
        self.tableModel.submitAll()

    def delete_rows(self, selected_rows):
        selected_rows.sort(reverse=True)  # 从后往前删除行，避免索引改变
        for row in selected_rows:
            self.tableModel.removeRow(row)
        self.tableModel.select()

    """"""

    def autoSize(self, x_margin=60, y_margin=40, parent=None, toCenter=False):
        """自动读取表格的尺寸,进而设置窗口显示大小"""
        # 行表头的长度+列表头的宽度即为表格宽度 +  父类widget显示需要的裕量
        width = self.horizontalHeader().length() + self.verticalHeader().width(
        ) + x_margin
        # 列表头的长度+行表头的高度即为表格高度  +  父类widget显示需要的裕量
        height = self.verticalHeader().length() + self.horizontalHeader(
        ).height() + y_margin

        screen = QGuiApplication.primaryScreen().availableGeometry()
        if width > 0.9 * screen.width():
            width = int(0.9 * screen.width())
        if height > 0.7 * screen.height():
            height = int(0.7 * screen.height())

        # 设置父类
        if parent is None:
            parent = self.parent()

        parent.resize(width, height)
        if toCenter:
            qr = parent.frameGeometry()
            # 将QWidget矩形框的中心点移到屏幕中心点
            qr.moveCenter(screen.center())
            # QWidget移动到qr的位置
            parent.move(qr.topLeft())

    def rememberState(self):
        selection_model = self.selectionModel()
        self.previous_selection = QItemSelection(selection_model.selection())
        self.previous_index = self.currentIndex()

    def restoreState(self):
        selection_model = self.selectionModel()
        selection_model.clearSelection()
        selection_model.select(self.previous_selection, QItemSelectionModel.ClearAndSelect)
        if self.previous_index.isValid():
            self.setCurrentIndex(self.previous_index)

    def keyPressEvent(self, event: PySide6.QtGui.QKeyEvent) -> None:
        if self.Ro_flag:
            super(VarTable, self).keyPressEvent(event)
            return

        if event.modifiers() == Qt.ControlModifier:
            if event.key() == Qt.Key_Up:
                # 行上移操作
                selected_rows = list(
                    set(map(lambda index: index.row(), self.selectedIndexes())))
                selected_rows.sort(reverse=False)
                if selected_rows[0] == 0:
                    QMessageBox.information(self, '提示', '已经是最顶部条目')
                    return super().keyPressEvent(event)
                self.move_row(selected_rows, selected_rows[0], selected_rows[0] - 1, True)
            elif event.key() == Qt.Key_Down:
                # 行下移操作
                selected_rows = list(
                    set(map(lambda index: index.row(), self.selectedIndexes())))
                selected_rows.sort(reverse=False)
                if selected_rows[-1] == self.tableModel.rowCount() - 1:
                    QMessageBox.information(self, '提示', '已经是最底部部条目')
                    return super().keyPressEvent(event)
                self.move_row(selected_rows, selected_rows[0], selected_rows[0] + 1, True)

            # elif event.key() == Qt.Key_Right:
            #     # index = self.currentIndex()
            #     # self.setCurrentIndex(self.tableModel.index(index.row() + 2, 2))
            #     # self.setFocus()
            #     # 行下移操作
            #     selected_rows = list(
            #         set(map(lambda index: index.row(), self.selectedIndexes())))
            #     selected_rows.sort(reverse=False)
            #     self.tableModel.submitAll()
            #     # self.move_row(selected_rows, selected_rows[0], 28, True)
            #     self.move_row([self.insert_src], self.insert_src, self.insert_tar, True)

        return super().keyPressEvent(event)

    def mousePressEvent(self, event:PySide6.QtGui.QMouseEvent) -> None:
        if event.button() == Qt.RightButton:
            global_pos = event.globalPos()

            # 将全局坐标转换为相对于 QTableView 的坐标
            viewport_pos = self.viewport().mapFromGlobal(global_pos)

            # 获取相对位置对应的列索引
            column_index = self.columnAt(viewport_pos.x())

            self.handleCellClicked(self.tableModel.index(0, column_index))
        return super().mousePressEvent(event)

    def move_row(self, selected_rows, sourceRow, destinationRow, dis_flag):
        """ 移动行   selected_rows  选择的行序列  sourceRow 原地址， destinationRow 目标地址  dis_flag 是否屏蔽信号 """
        # print(selected_rows, sourceRow, destinationRow)
        if dis_flag:
            # self.tableModel.dataChanged.disconnect(self.data_change_slot)
            self.tableModel.beforeUpdate.disconnect(self.handleBeforeUpdate)
        to_move_rowData = [self.tableModel.record(i) for i in selected_rows]

        selected_rows.sort(reverse=True)  # 从后往前删除行，避免索引改变
        for row in selected_rows:
            self.tableModel.removeRow(row)
        self.tableModel.select()
        self.tableModel.submitAll()

        update_value = self.get_middle_value(self.tableModel.record(destinationRow - 1).value(0),
                                              self.tableModel.record(destinationRow).value(0), len(selected_rows))

        # for i, rowData in enumerate(to_move_rowData):
        #     rowData.setValue(0, update_value[i])
        #     self.tableModel.insertRecord(destinationRow + i, rowData)
        #     print(self.tableModel.lastError())

        for i, rowData in enumerate(to_move_rowData):
            self.tableModel.insertRow(destinationRow + i)
            rowData.setValue(0, update_value[i])
            for j in range(rowData.count()):
                self.tableModel.setData(
                    self.tableModel.index(destinationRow + i, j), rowData.value(j))
            self.tableModel.submit()

        self.tableModel.submitAll()
        self.fresh_table()

        self.clearSelection()
        for i, rowData in enumerate(to_move_rowData):
            self.setCurrentIndex(self.tableModel.index(destinationRow + i, 2))

        self.current_index = self.currentIndex()
        self.timer_setFocus.setSingleShot(True)
        self.timer_setFocus.start(0)

        if dis_flag:
            # self.tableModel.dataChanged.connect(self.data_change_slot)
            self.tableModel.beforeUpdate.connect(self.handleBeforeUpdate)

    def get_middle_value(self, start, end, count):
        """ 从 start 到 end 取 count 个中间数据"""
        if start is None:
            start = 0
        if end is None:
            end = (int(start / 65535) + 1 + count) * 65535
        interval = (end - start) / (count + 1)
        result = []
        for i in range(count):
            result.append(int(start + interval * (i + 1)))
        return result

    def set_custom_focus(self):
        """ 设置焦点的定时器函数 放置 焦点丢失无法选择的问题 """
        self.setCurrentIndex(self.tableModel.index(self.current_index.row(), self.modifiedColumn))
        self.setFocus()
        self.setCurrentIndex(self.tableModel.index(self.current_index.row(), self.modifiedColumn))

    def insert_suited_row(self):
        """ 修改类型号后移动到相应位置 """
        # print('-----', self.insert_src, self.insert_tar)
        self.move_row([self.insert_src], self.insert_src, self.insert_tar, True)

    def fresh_table(self):
        self.rememberState()
        self.tableModel.select()
        self.restoreState()


class MySqlTableModel(QSqlTableModel):

    def resortKey(self):
        """
            笨办法实现resort key
            数据条数不能超过maxRow
        """
        maxRow = 500
        for i in range(self.rowCount()):
            self.setData(self.index(i, 0), i + maxRow)
        for i in range(self.rowCount()):
            self.setData(self.index(i, 0), i)

    def sort(self, column, order) -> None:
        """每次排序使得key和当前的排序一致"""
        super().sort(column, order)
        if column != 0:
            self.resortKey()

    # def setData(self, index, value, role=Qt.EditRole):
    #     if index.column() == 1 and value:  # Field A has changed
    #         self.blockSignals(True)  # prevent signalling data changed when updating dependent fields
    #         record = self.record(index.row())
    #         record.setValue(1, value)
    #         # calculate and set values for Field B and Field C
    #         record.setValue(2, value[0])
    #         record.setValue(3, value[1])
    #         self.setRecord(index.row(), record)
    #         self.blockSignals(False)  # re-enable signalling
    #         self.dataChanged.emit(index, index)  # notify views that Field A and dependent fields have changed
    #         return True
    #     return False


class InputDelegate(QStyledItemDelegate):

    def __init__(self, parent=None, inputType='int') -> None:
        super().__init__(parent)
        self.inputType = inputType

    def createEditor(self, parent, option, index):
        if self.inputType == 'category_id':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression('[A-Z]\d')  # 大写字母+数字
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            return editor
        elif self.inputType == 'comment':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression(
                '^[\u4E00-\u9FA5A-Za-z0-9_]+$')  # 中文、英文、数字包括下划线
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            return editor
        elif self.inputType == 'comment_text':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression(
                '^[\u4E00-\u9FA5A-Za-z0-9_]*$')  # 中文、英文、数字包括下划线和空
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            return editor
        elif self.inputType == 'no_edit':  # action_define这列不允许手动修改
            return None
        elif self.inputType == 'var_type':
            editor = QtWidgets.QComboBox(parent)
            editor.addItems(['int', 'float', 'bit', 'enum'])
            return editor
        elif self.inputType == 'bool':
            editor = QtWidgets.QCheckBox(parent)
            return editor
        elif self.inputType == 'int':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression('^-?\d+$|^$')  # 整数
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            editor.setEnabled(True)
            return editor
        elif self.inputType == 'float':
            # editor = QtWidgets.QLineEdit(parent)
            # reg = QRegularExpression('^(-?\d+)(\.\d+)?$|^$')  # 浮点数
            # validator = QRegularExpressionValidator(reg)
            # editor.setValidator(validator)
            # if index.model().index(index.row(), 12).data() == 1:
            #     pass
            # else:
            #     editor.setEnabled(False)
            # return editor
            if index.model().index(index.row(), 12).data() == 1:
                editor = QtWidgets.QLineEdit(parent)
                reg = QRegularExpression('^(-?\d+)(\.\d+)?$|^$')  # 浮点数
                validator = QRegularExpressionValidator(reg)
                editor.setValidator(validator)
                return editor
            else:
                return None
        elif self.inputType == 'str':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression('^[A-Za-z]+.*$|^$')  # 字符串,必须字母开头
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            return editor
        elif self.inputType == 'unit':
            editor = QtWidgets.QLineEdit(parent)
            reg = QRegularExpression('^[\s\S]*$')  # 单位， 可以有特殊字符
            validator = QRegularExpressionValidator(reg)
            editor.setValidator(validator)
            return editor
        else:
            return super().createEditor(parent, option, index)

    def paint(self, painter, option, index):
        """ 重载 paint 事件， 给 QTableView 添加背景颜色 """
        # 获取所有的 类型号
        type_name_temp = index.model().data(index.model().index(index.row(), 1), Qt.DisplayRole)
        type_name_list = []
        for i in range(index.model().rowCount()):
            type_name_list.append(index.model().data(index.model().index(i, 1), Qt.DisplayRole))
        # 去重、排序
        type_name_list = list(set(type_name_list))
        if None in type_name_list:
            type_name_list.remove(None)
        type_name_list.sort()
        # 去掉空字符是为了应对在添加新条目是出现新行
        if '' in type_name_list:
            type_name_list.remove('')
        else:
            # 根据在list里的奇偶性区分颜色区域
            try:
                if type_name_list.index(type_name_temp) % 2 == 0:
                    painter.fillRect(option.rect, QColor(240, 240, 240, 255))  # 灰色
                    # painter.fillRect(option.rect, QColor(255, 0, 0, 20))      # 粉红色
                else:
                    pass
            except:
                pass
        # 将 repeat_err 单元格 设置成红色
        if index.data() == 'repeat_err':
            painter.fillRect(option.rect, QColor(255, 0, 0, 200))  # 粉红色

        # 将默认数据不在范围之内的数据变红
        if index.column() == 7:
            # if index.data() == '-3':
            # if index.data() and index.model().data(index.model().index(index.row(), 9)):
            #     print(float(index.model().data(index.model().index(index.row(), 9))) , float(index.data()))
            if index.data() != '' and index.model().data(index.model().index(index.row(), 9)) != '':
                if float(index.model().data(index.model().index(index.row(), 9))) < float(index.data()):
                    painter.fillRect(option.rect, QColor(255, 0, 0, 200))  # 粉红色
                else:
                    pass
            # if index.data() and index.model().data(index.model().index(index.row(), 8)):
            #     print(float(index.model().data(index.model().index(index.row(), 8))) , float(index.data()))
            #     print(float(index.model().data(index.model().index(index.row(), 8))) > float(index.data()))
            if index.data() != '' and index.model().data(index.model().index(index.row(), 8)) != '':
                if float(index.model().data(index.model().index(index.row(), 8))) > float(index.data()):
                    painter.fillRect(option.rect, QColor(255, 0, 0, 200))  # 粉红色
                else:
                    pass


            # if float(index.model().data(index.model().index(index.row(), 9))) < float(index.data()) or float(index.model().data(index.model().index(index.row(), 8))) > float(index.data()):
            #     painter.fillRect(option.rect, QColor(255, 0, 0, 200))  # 粉红色

        # 将缺省值为0的屏蔽掉不显示， 7 为 var_default 在表中的索引 由于不可重复调用所以用了具体的值
        if index.column() == 7 and index.data() == 0:
            return

        # 调用继承函数继续添加文字等操作
        super().paint(painter, option, index)

    def displayText(self, value, locale):
        if self.inputType == 'bool':
            # print(value, type(value))
            if value:
                if value == 1 or value == '1':
                    return 'True'
                else:
                    return ''
            else:
                return ''
        else:
            text = super(InputDelegate, self).displayText(value, locale)
            return text

    # def setEditorData(self, editor, index):
    #     print(index)
    #     if self.inputType == 'float':
    #         if index.model().index(index.row(), 12).data() == 1:
    #             super().setEditorData(editor, index)
    #         else:
    #             editor.setValue('')
    #     else:
    #         super().setEditorData(editor, index)
    #
    # def setData(self, index, role):
    #     print(index)
    #     if self.inputType == 'float':
    #         if index.model().index(index.row(), 12).data() == 1:
    #             return super().data(index, role)
    #         else:
    #             print(11111)
    #             return None
    #     else:
    #         return super().data(index, role)

    # def setData(self, index, value, role=Qt.EditRole):
    #     if not index.isValid() or role != Qt.EditRole:
    #         return False
    #
    #     if index.column() == 1 and value == '':
    #         QMessageBox.warning(None, "Warning", "Field cannot be empty!")
    #         return False  # 不允许提交不允许为空的字段
    #     elif index.column() == 2 and value == '':
    #         QMessageBox.warning(None, "Warning", "Field cannot be empty!")
    #         return False  # 不允许提交不允许为空的字段
    #     elif index.column() == 3 and value == '':
    #         QMessageBox.warning(None, "Warning", "Field cannot be empty!")
    #         return False  # 不允许提交不允许为空的字段
